package top.zhangjianyong.blog.client;

import cn.hutool.core.io.IoUtil;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import top.zhangjianyong.blog.config.OssProperties;
import java.io.InputStream;

/**
 * OSS 客户端封装类，负责初始化、文件上传和资源释放
 * 建议通过配置文件或环境变量注入 AK/SK
 *
 * @author zhangjianyong
 * @since 2025/8/6
 */
public class OssClient {
    // OSS 客户端实例
    private final OSS ossClient;
    private final OssProperties properties;


    /**
     * 通过 OssProperties 配置对象初始化 OSS 客户端
     * 便于与 Spring Boot 配置体系集成
     *
     * @param properties OSS 配置属性对象，需包含 endpoint、accessKeyId、accessKeySecret、region、bucketName
     */
    public OssClient(OssProperties properties) {
        this.properties = properties;
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(properties.getAccessKeyId(), properties.getAccessKeySecret());
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 推荐使用 V4 签名
        clientBuilderConfiguration.setSignatureVersion(com.aliyun.oss.common.comm.SignVersion.V4);
        this.ossClient = OSSClientBuilder.create()
            .endpoint(properties.getEndpoint())
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(properties.getRegion())
            .build();
    }

    /**
     * 上传文件到 OSS
     *
     * @param objectName  目标对象名（含路径）
     * @param inputStream 文件输入流
     * @return PutObjectResult 上传结果
     * @throws OSSException    OSS服务端异常
     * @throws ClientException 客户端异常
     */
    public PutObjectResult putObject(String objectName, InputStream inputStream) throws OSSException, ClientException {
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(getBucketName(), objectName, inputStream);
            return ossClient.putObject(putObjectRequest);
        } finally {
            IoUtil.close(inputStream);
        }

    }

    public OSSObject getObject(String key) {
        return ossClient.getObject(getBucketName(), key);
    }

    public String getBucketName() {
        return properties.getBucketName();
    }

    /**
     * 关闭 OSS 客户端，释放资源
     */
    public void shutdown() {
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}
